#pragma once
#include <thread>
#include <condition_variable>
#include <mutex>
#include <functional>
#include <map>
#include "CommonDef.h"
#include "SessionView.h"
#include "SessionModel.h"

typedef std::function<const OutcutActionInfo (const SessionActionInfo&)> AnlysizeCallback;
typedef std::function<void (const OutcutActionInfo&)> PlayerActionCallback;

class SessionController : public Singleton<SessionController>
{
public:
    SessionController();

    ~SessionController();
public:
    void ready2Game();

    void userSitPostion(Postion ps);

    void playerAction(const OutcutActionInfo& outputAction);

private:
    void playerOutputChess(const OutcutActionInfo &outputAction);

    void playerGangChess(const OutcutActionInfo& outputAction);

    void playerPengChess(const OutcutActionInfo& outputAction);

    void playerChiChess(const OutcutActionInfo& outputAction);

    void playerAnGangChess(const OutcutActionInfo& outputAction);

    void playerXuGangChess(const OutcutActionInfo& outputAction);

    void playerHuChess(const OutcutActionInfo& outputAction);

    void playerZimoChess(const OutcutActionInfo& outputAction);

public:
    const OutcutActionInfo anlysizeAi(const SessionActionInfo& sessionActionInfo);

private:
    const OutcutActionInfo anlysizeAiOutput(const SessionActionInfo& sessionActionInfo);

    const OutcutActionInfo anlysizeAiGang(const SessionActionInfo& sessionActionInfo);

    const OutcutActionInfo anlysizeAiPeng(const SessionActionInfo& sessionActionInfo);

    const OutcutActionInfo anlysizeAiChi(const SessionActionInfo& sessionActionInfo);

    const OutcutActionInfo anlysizeAiAnGang(const SessionActionInfo& sessionActionInfo);

    const OutcutActionInfo anlysizeAiXuGang(const SessionActionInfo& sessionActionInfo);

    const OutcutActionInfo anlysizeAiHu(const SessionActionInfo& sessionActionInfo);

    const OutcutActionInfo anlysizeAiZimo(const SessionActionInfo& sessionActionInfo);
private:
    void startSession();

    void startDispatch();

private:
    void disptchStartChess2Ps(Postion ps);

    void disptchJumpChess2Ps(Postion ps);

private:
    void checkHandChessAfterDispath();

    void updateChess2NextPsPlayer(Postion actionPs, const Chess& chess);
private:
    SessionAction checkHandChess(const std::vector<Chess>& chessVec, const std::vector<KindChess>& handWeaveChess, std::vector<KindChess>& weaveResult);

    bool checkHandChessAnGang(const std::vector<Chess>& chessVec, std::vector<KindChess>& weaveResult);

    bool checkHandChessXuGang(const std::vector<Chess>& chessVec, const std::vector<KindChess>& handWeaveChess, std::vector<KindChess>& weaveResult);

    bool checkHandChessZimo(const std::vector<Chess>& chessVec, std::vector<KindChess>& weaveResult);

private:
    SessionAction checkOutputChess2Action(Postion currentPs, Postion outputPs, const std::vector<Chess>& chessVec, const Chess& chess, std::vector<KindChess>& kindResult);

    bool checkOutputChessChi(Postion currentPs, Postion outputPs, const std::vector<Chess>& chessVec, const Chess& chess, std::vector<KindChess>& kindResult);

    bool checkOutputChessPeng(const std::vector<Chess>& chessVec, const Chess& chess, std::vector<KindChess>& kindResult);

    bool checkOutputChessGang(const std::vector<Chess>& chessVec, const Chess& chess, std::vector<KindChess>& kindResult);

    bool checkOutputChessHu(const std::vector<Chess>& chessVec, const Chess& chess, std::vector<KindChess>& kindResult);

private:
    SitPostion getSitPostionByPs(Postion ps);
private:
    SessionView* m_view;
    SessionModel* m_model;
    std::map<short, AnlysizeCallback> m_anlysizeAiActionCallback;
    std::map<short, PlayerActionCallback> m_playerActionCallback;
};

